// Created By: Carl Dell (cjd5222@psu.edu)
// Created On: March 31, 2012
// Last Edit:  April 7, 2012

package com.srm.psu.glf;

import android.app.AlertDialog;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class DbHelper extends SQLiteOpenHelper
{ 
	// Database name
    private static final String DB_NAME = "UdderMaddness";			
    
	// High Score table name and column name definitions
	private static final String SCORE_TABLE = "HighScores";
	private static final String SCORE_ID = "ScoresId";
	private static final String SCORE = "Score";
	
	// Options table name and column definitions
	private static final String OPTIONS_TABLE = "Options";
	private static final String OPTIONS_ID = "OptionsId";
	private static final String OPTIONS_FX_ON = "FxEnabled";
	private static final String OPTIONS_BG_ON = "BgEnabled";
	
	// Maximum number of high scores
	private static final int MAX_NUM_SCORES = 10;
	
	// Context of the DbHelper
    private final Context context;
    
	public DbHelper(Context context)
	// PRE:  context is initialized
	// POST: Creates a default DbHelper object
	{
		super(context, DB_NAME, null, 1);
        this.context = context;
	}
	
	public void onCreate(SQLiteDatabase db)
	// PRE:  db is initialized
	// POST: Adds necessary tables to database
	{
		Cursor c;
		
		try
		{
			db.execSQL(String.format("CREATE TABLE IF NOT EXISTS %s ("
					+ "%s INTEGER PRIMARY KEY AUTOINCREMENT,"
					+ "%s INTEGER);",
					SCORE_TABLE, SCORE_ID, SCORE));
			
			db.execSQL(String.format("CREATE TABLE IF NOT EXISTS %s ("
					+ "%s INTEGER PRIMARY KEY AUTOINCREMENT,"
					+ "%s INTEGER,"
					+ "%s INTEGER);",
					OPTIONS_TABLE, OPTIONS_ID, OPTIONS_FX_ON, OPTIONS_BG_ON));
			
			c = db.rawQuery(String.format("SELECT %s, %s FROM %s LIMIT 1",
																OPTIONS_FX_ON, OPTIONS_BG_ON, OPTIONS_TABLE), null);
		
			if ((c != null) && (!c.moveToFirst()))
			{
				db.execSQL(String.format("INSERT INTO %s (%s, %s) VALUES (1, 1);",
																OPTIONS_TABLE, OPTIONS_FX_ON, OPTIONS_BG_ON));
			}
		}
		catch (SQLException e)
		{
			throwError(e);
		}
	}
	
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
	{
		db.execSQL("DROP TABLE IF EXISTS " + DB_NAME);
		onCreate(db);
	}
	
	public void createDB()
	// POST: Creates all tables for the Udder Maddness database
	{
		try
		{
			onCreate(getWritableDatabase());
		}
		catch (SQLException e)
		{
			throwError(e);
		}
	}
	
	public void addScore(int score)
	// PRE:  score > 0
	// POST: Adds an entry to SCORE_TABLE with SCORE = score
	{
		try
		{
			getWritableDatabase().execSQL(String.format("INSERT INTO %s (%s) VALUES (%d);",
															SCORE_TABLE, SCORE, score));
		}
		catch (SQLException e)
		{
			throwError(e);
		}
	}
	
	public void setFxVol(boolean enabled)
	// PRE:  enabled is initialized
	// POST: Sets the sound effects volume option to enabled
	{
		try
		{
			getWritableDatabase().execSQL(String.format("UPDATE %s SET %s = %d WHERE 1 = 1;",
															OPTIONS_TABLE, OPTIONS_FX_ON, enabled ? 1 : 0));
		}
		catch (SQLException e)
		{
			throwError(e);
		}
	}
	
	public void setBgVol(boolean enabled)
	// PRE:  enabled is initialized
	// POST: Sets the background music volume option to enabled
	{
		try
		{
			getWritableDatabase().execSQL(String.format("UPDATE %s SET %s = %d WHERE 1 = 1;",
															OPTIONS_TABLE, OPTIONS_BG_ON, enabled ? 1 : 0));
		}
		catch (SQLException e)
		{
			throwError(e);
		}
	}
	
	@SuppressWarnings("finally")
	public int[] getHighScores()
	// POST: Returns an array of size MAX_NUM_SCORES that contains the high scores, sorted from highest to lowest
	{
		int[] results = new int[MAX_NUM_SCORES];
		int logSize = 0;
		Cursor c;
		
		try
		{
			c = getWritableDatabase().rawQuery(String.format("SELECT %s FROM %s ORDER BY %s DESC LIMIT %d",
																SCORE, SCORE_TABLE, SCORE, MAX_NUM_SCORES), null);
			
			if (c != null )
			{
	            if  (c.moveToFirst())
	            {
	            	do
	                {
	            		results[logSize++] = c.getInt(c.getColumnIndex(SCORE));
	                } while (c.moveToNext());
	            }
			}
		}
		catch (SQLException e)
		{
			throwError(e);
		}
		finally
		{
			return results;
		}
	}
	
	public boolean getFxVol()
	// POST: Returns the sound effects volume option
	{
		Cursor c;
		boolean enabled = true;
		
		try
		{
			c = getWritableDatabase().rawQuery(String.format("SELECT %s FROM %s LIMIT 1",
																OPTIONS_FX_ON, OPTIONS_TABLE), null);
		
			if (c != null)
			{
	            if  (c.moveToFirst())
	            {
	            	enabled = (c.getInt(c.getColumnIndex(OPTIONS_FX_ON)) == 1) ? true : false;
	            }
			}
		}
		catch (SQLException e)
		{
			throwError(e);
		}
		finally
		{
			return enabled;
		}
	}
	
	public boolean getBgVol()
	// POST: Returns the background volume option
	{
		Cursor c;
		boolean enabled = true;
		
		try
		{
			c = getWritableDatabase().rawQuery(String.format("SELECT %s FROM %s LIMIT 1",
																OPTIONS_BG_ON, OPTIONS_TABLE), null);
		
			if (c != null)
			{
	            if  (c.moveToFirst())
	            {
	            	enabled = (c.getInt(c.getColumnIndex(OPTIONS_BG_ON)) == 1) ? true : false;
	            }
			}
		}
		catch (SQLException e)
		{
			throwError(e);
		}
		finally
		{
			return enabled;
		}
	}
	
	public void emptyDb()
	// POST: Removes all tables from the database that were created
	{
		try
		{
			getWritableDatabase().execSQL(String.format("DROP TABLE IF EXISTS %s", SCORE_TABLE));
			getWritableDatabase().execSQL(String.format("DROP TABLE IF EXISTS %s", OPTIONS_TABLE));
		}
		catch (SQLException e)
		{
			throwError(e);
		}
	}
	
	private void throwError(Exception e)
	// PRE:  e is initialized
	// POST: Throws an error
	{
		AlertDialog alertDialog = new AlertDialog.Builder(context).create();
		
		alertDialog.setTitle("SQL Error");
		
		alertDialog.setMessage(e.getMessage());
		
		alertDialog.show();
	}
}
